﻿// Copyright (c) egmkang wang. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace XServer.Grains
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Orleans;
    using Orleans.Concurrency;
    using GrainInterfaces;
    using XServer.SDK;

    [Reentrant]
    public class AllGatewayGrain : Grain, IAllGatewayGrain
    {
        Dictionary<string, IGatewayGrain> gateway = new Dictionary<string, IGatewayGrain>();
        Dictionary<string, IGatewayObserver> listener = new Dictionary<string, IGatewayObserver>();

        public Task RecvMessage(ushort msgid, Immutable<byte[]> buffer)
        {
            throw new Exception("Gateway Dose not process client message");
        }

        public Task RegisterGateway(string key)
        {
            if (!this.gateway.ContainsKey(key))
            {
                IGatewayGrain grain = grain = this.GrainFactory.GetGrain<IGatewayGrain>(key);
                
                if (grain != null)
                {
                    this.gateway.Add(key, grain);
                }
            }
            return TaskDone.Done;
        }

        public Task UnRegisterGateway(string key)
        {
            this.gateway.Remove(key);
            return TaskDone.Done;
        }

        public Task RegisterObserver(string key, IGatewayObserver ob)
        {
            if (this.listener.ContainsKey(key))
                this.listener.Remove(key);
            this.listener.Add(key, ob);
            return TaskDone.Done;
        }

        public Task UnRegisterObserver(string key)
        {
            this.listener.Remove(key);
            return TaskDone.Done;
        }

        public Task SendMessage(int destType, long dest, Immutable<byte[]> buffer)
        {
            foreach (var item in this.listener)
            {
                try
                {
                    item.Value.OnRecvMessage(destType, dest, buffer);
                }
                catch (Exception e)
                {
                    LoggerProvider.Logger.Error("AllGateGrain.SendMessage, DestType:{0}, Dest:{1}, ErrorMessage:{2}"
                        , destType, dest, e.Message);
                }
            }
            return TaskDone.Done;
        }
    }
}
